//
// finFit2.cc
// - fit day-to-day volatility of a financial product
// 
// Requirements:
// - root v3.10
// - RooFit 1.04
// - finReadCsv.cc, finReadCsv.hh
//
// Usage:
// > root
// root> gSystem->SetIncludePath("-Wno-deprecated -Wno-overloaded-virtual");
// root> gSystem->Load("libRooFitCore.so");
// root> gSystem->Load("libRooFitModels.so");
// root> .L finReadCsv.cc+
// root> .x finFit2.cc+
//

#include <stdlib.h>

#include "TCanvas.h"
#include "TH2F.h"

#include "RooFitCore/RooRealVar.hh"
#include "RooFitCore/RooGenericPdf.hh"
#include "RooFitCore/RooDataSet.hh"
#include "RooFitCore/RooPlot.hh"
#include "RooFitModels/RooGaussian.hh"

#include "finReadCsv.hh"

using namespace RooFit;

//
// fit options
//
// "m" = MIGRAD only, i.e. no MINOS
// "s" = estimate step size with HESSE before starting MIGRAD
// "h" = run HESSE after MIGRAD
// "e" = Perform extended MLL fit
// "0" = Run MIGRAD with strategy MINUIT 0 (faster, but no corr. matrix at end)
// 
// "q" = Switch off verbose mode
// "l" = Save log file with parameter values at each MINUIT step
// "v" = Show changed parameters at each MINUIT step
// "t" = Time fit
// "r" = Save fit output in RooFitResult object

// normalized Lorentzian	   
// L(x,x0,s) = 1/pi * 0.5*s / ( (x-x0)^2) + (0.5s)^2 )

// std::vector<quote_s> quotes; ---- not supported in root 3.10!

//--- maximum number of daily quotations
#define MAXQUOTES (6000)

//
// fit quotations exponential f. of time with a random spread
// proportional to the predicted quotation
//

int fitQuotes ()
{
  //
  // structure to store quotations data
  //
  quote_s qq[MAXQUOTES];
  vquotes_s vquotes(qq, MAXQUOTES);
  
  TString fname("./VFINX.csv");
  
  if (readCsvQuotes(fname, vquotes)) {
    return EXIT_FAILURE;
  }

  //--- dataset variables
  RooRealVar qvar("qvar", "qvar", -0.5, 0.5, "%var");

#if 1
  //--- parameters
  RooRealVar mean("mean", "mean", -1, 1, "%var");
  mean.setVal(0);
  RooRealVar sigma("sigma", "sigma", 0.1, 100, "%var");
  sigma.setVal(1);

  //
  // fit ln(q(i+0)/q(i)) as Gaussian distribution
  // 
  RooGenericPdf vty("vty", "volatility",
		    "exp(-0.5*pow((qvar-mean)/log(1+sigma/100),2))",
		    RooArgSet(qvar,mean,sigma));
#endif

#if 0
  //--- parameters
  RooRealVar mean("mean", "mean", -1, 1, "%var");
  mean.setVal(0);
  RooRealVar sigma("sigma", "sigma", 0.001, 1, "%var");
  sigma.setVal(0.01);

  //
  // fit ln(q(i+0)/q(i)) as Gaussian distribution
  // 
  RooGenericPdf vty("vty", "volatility",
		    "exp(-0.5*pow((qvar-mean)/sigma,2))",
		    RooArgSet(qvar,mean,sigma));
#endif

  //--- dataset
  RooDataSet data("data", "data", RooArgSet(qvar));

  //
  // fill dataset
  //
  float q0 = vquotes.q[0].quote;
  float q1;
  for(unsigned int i=1; i < vquotes.size; i++) {
    q1 = vquotes.q[i].quote;
    qvar.setVal(log(q1/q0));
    data.add(RooArgSet(qvar));

#if 0
    std::cout
      << vquotes.q[i].quote << " "
      << log(q1/q0) << " "
      << endl;
#endif

    q0 = q1;
  }
  
  vty.fitTo(data, "0q");

  RooPlot* qvarFrame = qvar.frame(-0.08,0.08,100);
  data.plotOn(qvarFrame);
  vty.plotOn(qvarFrame);
  qvarFrame->Draw();

  return EXIT_SUCCESS;
}

//
// main
//

void finFit2()
{
  fitQuotes();
}
